﻿using System;
using System.IO;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

namespace Platformer1.GameScreens
{
    class GameplayScreen:GameScreen
    {
        private SpriteBatch spriteBatch;
        private GraphicsDevice graphics;

        private const Buttons ContinueButton = Buttons.A;
        private bool wasContinuePressed;
        private Level level;
        private ContentManager content;

        // Global content.
        private SpriteFont hudFont;

        private Texture2D winOverlay;
        private Texture2D loseOverlay;
        private Texture2D diedOverlay;

        public Texture2D healtTextrue;
        public Texture2D damageTexture;

        private int levelIndex = -1;
        private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);


       public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }

       public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            spriteBatch = new SpriteBatch(ScreenManager.Game.GraphicsDevice);

            if (graphics == null)
                graphics = ScreenManager.GraphicsDevice;

            // Load fonts
            hudFont = content.Load<SpriteFont>("Fonts/Hud");

            // Load overlay textures
            winOverlay = content.Load<Texture2D>("Overlays/you_win");
            loseOverlay = content.Load<Texture2D>("Overlays/you_lose");
            diedOverlay = content.Load<Texture2D>("Overlays/you_died");
            healtTextrue = content.Load<Texture2D>("debug2");
            damageTexture = content.Load<Texture2D>("debug");

            LoadNextLevel();
        }

       public override void UnloadContent()
        {
            content.Unload();
        }

       public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            if (IsActive)
            {
                level.Update(gameTime);
            }
        }
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamepadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamepadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
            else
            {
                // Exit the game when back is pressed.
                //if (gamepadState.Buttons.Back == ButtonState.Pressed)
                //    Exit();

                bool continuePressed =
                    keyboardState.IsKeyDown(Keys.Space) ||
                    gamepadState.IsButtonDown(ContinueButton);

                // Perform the appropriate action to advance the game and
                // to get the player back to playing.
                if (!wasContinuePressed && continuePressed)
                {
                    if (!level.Players[playerIndex].IsAlive)
                    {
                        foreach (Player p in level.Players)
                            level.StartNewLife(p);
                    }
                    else if (level.TimeRemaining == TimeSpan.Zero)
                    {
                        if (level.ReachedExit)
                            LoadNextLevel();
                        else
                            ReloadCurrentLevel();
                    }
                }

                wasContinuePressed = continuePressed;
 
            }
            
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            //graphics.GraphicsDevice.Clear(Color.Black);

            level.Draw(gameTime, spriteBatch);

            DrawHud();
            
            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0)
                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
        }

        private void LoadNextLevel()
        {
            /*
            // Find the path of the next level.
            string levelPath;
            


            // Loop here so we can try again when we can't find a level.
           
            while (true)
            {
                // Try to find the next level. They are sequentially numbered txt files.
                levelPath = String.Format("Levels/{0}.txt", ++levelIndex);
                levelPath = "Content/" + levelPath;
                if (File.Exists(levelPath))
                    break;

                // If there isn't even a level 0, something has gone wrong.
                if (levelIndex == 0)
                    throw new Exception("No levels found.");

                // Whenever we can't find a level, start over again at 0.
                levelIndex = -1;
            }

            // Unloads the content for the current level before loading the next one.
            if (level != null)
                level.Dispose();

            // Load the level.
            

            level = new Level(ScreenManager.Game.Services, levelPath);
             **/
            level = new Level(ScreenManager.Game.Services, "Content/Levels/0.txt");
 
        }

        private void ReloadCurrentLevel()
        {
            --levelIndex;
            LoadNextLevel();
        }

        private void DrawHud()
        {
            spriteBatch.Begin();

            Rectangle titleSafeArea = ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
            Color timeColor;
            if (level.TimeRemaining > WarningTime ||
                level.ReachedExit ||
                (int)level.TimeRemaining.TotalSeconds % 2 == 0)
            {
                timeColor = Color.Yellow;
            }
            else
            {
                timeColor = Color.Red;
            }
            DrawShadowedString(hudFont, timeString, hudLocation, timeColor);

            // Draw score
            float timeHeight = hudFont.MeasureString(timeString).Y;
            DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);
            
            // Determine the status overlay message to show.
            Texture2D status = null;
            if (level.TimeRemaining == TimeSpan.Zero)
            {
                if (level.ReachedExit)
                {
                    status = winOverlay;
                }
                else
                {
                    status = loseOverlay;
                }
            }
            else if (!level.Players[0].IsAlive && level.deathTime <= 0)
            {
                status = diedOverlay;
            }

            if (status != null)
            {
                // Draw status message.
                Vector2 statusSize = new Vector2(status.Width, status.Height);
                spriteBatch.Draw(status, center - statusSize / 2, Color.White);
            }
            //Draw Player 1 health
            int healthWidth = level.Players[0].health;
            int damageWidth = 100 - healthWidth;

            spriteBatch.Draw(healtTextrue, new Rectangle(0, 70, healthWidth, 10), Color.White);
            spriteBatch.Draw(damageTexture, new Rectangle(healthWidth, 70, 100 - healthWidth, 10), Color.White);

            //Draw player 2 health 
            /*
            if (level.Players.Length == 2)
            {
                healthWidth = level.Players[1].health;
                damageWidth = 100 - healthWidth;

                spriteBatch.Draw(healtTextrue, new Rectangle(0, 90, healthWidth, 10), Color.White);
                spriteBatch.Draw(damageTexture, new Rectangle(healthWidth, 90, 100 - healthWidth, 10), Color.White);
            }
            */
            spriteBatch.End();
        }

        private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
        {
            spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
            spriteBatch.DrawString(font, value, position, color);
        }

    }
}
